package com.lp.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.lp.bean.IotHistorySensorData;
import com.lp.bo.IotNodeInfoBO;
import com.lp.bo.IotSceneInfoBO;
import com.lp.bo.IotSensorInfoBO;
import com.lp.cache.CacheName;
import com.lp.cache.ProCacheUtil;
import com.lp.common.Code;
import com.lp.common.CodeIot;
import com.lp.service.IotSensorInfoService;
import com.lp.util.Calculator;
import com.lp.util.DateUtils;
import com.lp.util.ObjectUtil;
import com.lp.util.iot.IotTrigger;

@Service
public class IotSensorInfoServiceImpl extends BaseServiceImpl implements IotSensorInfoService {

	public static void main(String[] args) {
		
	}
	
	@Override
	public Map<String, Object> updateRealTimeData(IotSensorInfoBO obj) {
		Map<String, Object> resultMap = getResultMap();
		try{
			// 通过网关缓存 deviceCode -> nodeInfo -> id (or nodeId)
			IotNodeInfoBO iotNodeInfo = ProCacheUtil.getCache(CacheName.NODEINFO_DEVICECODE, obj.getDevice_code());
			
			if(ObjectUtil.isEmpty(iotNodeInfo)){
				// 这个设备已经离线了；返回错误，让用户重新登录；
				putStatusCode(resultMap, CodeIot.DEVICE_STATUS.OFFLINE);
				// 服务端发送重新登录的命令
				return resultMap;
			}
			
			if(  ObjectUtil.isEmpty(iotNodeInfo.getIot_node_status()) || iotNodeInfo.getIot_node_status() != 16 ){
				// 缓存在线
				iotNodeInfo.setIot_node_status(CodeIot.DEVICE_STATUS.ONLINE);
				iotNodeInfo.setMtime(new Date());
				
				// 如果设备不在线，则让设备在线
				dao.update("IotNodeInfo.updateNodeStatus", iotNodeInfo);
			}
			
			// 网关没有项目信息
			IotSceneInfoBO sceneBo = ProCacheUtil.getCache(CacheName.SCENEINFO, iotNodeInfo.getScene_id().toString() );
			if(ObjectUtil.isEmpty(sceneBo)){
				return resultMap;
			}
			
			obj.setNode_name(iotNodeInfo.getName());
			obj.setNode_id( iotNodeInfo.getId() );
			// 获取传感器缓存信息
			IotSensorInfoBO sensorInfo = ProCacheUtil.getCache(CacheName.SENSORINFO_NSP, obj.getNode_id()+"-"+obj.getSensor_device_id()+"-"+obj.getPort_id(), obj);
			
			if( ObjectUtil.isEmpty(sensorInfo) ){
				// 不存在的数据
				return resultMap;
			}
			obj.setId(sensorInfo.getId());
			
			// 这边判断如果是经纬度的传感器信息，则需要更新网关信息的经纬度数据
			if( sensorInfo.getIot_sensor_type()!=null && sensorInfo.getIot_sensor_type() == CodeIot.SENSOR_TYPE.POSITION +0 ){
				iotNodeInfo.setLonLat( obj.getStr_sdata() );
				dao.update("IotNodeInfo.update", iotNodeInfo) ;
			}
			
			// 公式转化 - 有公式则将数据通过公式转换一下
			if(ObjectUtil.isNotEmpty(sensorInfo.getFormula_up()) && sensorInfo.getFormula_up().contains("x")  ){
				obj.setSdata( (float) Calculator.conversion( sensorInfo.getFormula_up().replaceAll("x", obj.getSdata()+"")));
			}
			// 小数位处理
			if(  sensorInfo.getSdata_degree()==null ){
				sensorInfo.setSdata_degree(2);
			}
			if( ObjectUtil.isEmpty( obj.getStr_sdata()) ){
				float ft = obj.getSdata() ;
				BigDecimal bd  = new BigDecimal((double)ft);  
				bd   =  bd.setScale(sensorInfo.getSdata_degree() ,4);  
				ft = bd.floatValue() ;
				obj.setSdata(ft);
				obj.setRequest_sdata(obj.getSdata());				
			}
			
			//*** 20190405 如果是配置数据，则直接更新数据库，并更新缓存，数据不进入历史表里面
			if( sensorInfo.getData_type() == 1 ){
				// 配置数据
				Integer num = dao.update("IotSensorInfo.updateRealTimeData", obj);
				if( num >0){
					IotSensorInfoBO sensor = ProCacheUtil.getCache(CacheName.SENSORINFO, sensorInfo.getId().toString() );
					sensor.setStr_sdata( obj.getStr_sdata() );
					return resultMap ;
				}
			}
			
			// 上传一些无用的传感器信息
			if( ObjectUtil.isEmpty(sensorInfo)){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_DATA);
				return resultMap;
			}
			// 网关时间更新
			iotNodeInfo.setMtime(new Date());
			// 补充字段给触发器链条使用
			obj.setMeasure_unit_type(sensorInfo.getMeasure_unit_type());
			
			obj.setScene_name( sceneBo.getName() );
			
			if( IotTrigger.trigger(obj,dao) >= 0){
				// 设置传感器id
				obj.setId(sensorInfo.getId());
				Integer num = dao.update("IotSensorInfo.updateRealTimeData_byid", obj);
				if(num > 0 ){
					// 传感器数据更新成功
					IotSensorInfoBO sensor = ProCacheUtil.getCache(CacheName.SENSORINFO, sensorInfo.getId().toString() );
					// 确定是否是定位str_sdata 类型
					if(ObjectUtil.isNotEmpty( obj.getStr_sdata())){
						if(  sensorDataStratety(obj.getStr_sdata() ,sensor.getStr_sdata() ,sensor)  ) {
							// 添加历史数据。目前只添加变化的历史数据
							IotHistorySensorData iotSensorHistory = new IotHistorySensorData();
							iotSensorHistory.setSensor_id(sensor.getId());
							iotSensorHistory.setSdata(obj.getStr_sdata());
							iotSensorHistory.setAtime(obj.getMtime());
							dao.insert("IotHistorySensorData.insert", iotSensorHistory);							
						}
						sensor.setStr_sdata( obj.getStr_sdata() );
					}else{
						//  正常行 sdata
						if(sensor.getSdata() == null ){
							sensor.setSdata(-11111f);
						}
						if( sensorDataStratety(obj.getSdata() ,sensor.getSdata() ,sensor) ){
							// 添加历史数据。目前只添加变化的历史数据
							IotHistorySensorData iotSensorHistory = new IotHistorySensorData();
							iotSensorHistory.setSensor_id(sensor.getId());
							iotSensorHistory.setSdata(obj.getSdata().toString());
							iotSensorHistory.setAtime(obj.getMtime());
							dao.insert("IotHistorySensorData.insert", iotSensorHistory);
						}
						sensor.setSdata(obj.getSdata());
						sensor.setRequest_sdata(obj.getRequest_sdata());
					}
					sensor.setMtime(obj.getMtime());
				}
			}
		}catch(Exception e){
			super.exception(e, obj);
			putStatusCode(resultMap, Code.ResponseCode.SystemCode.ERROR);
		}
		return resultMap;
	}
	
	private Boolean sensorDataStratety(Object oldvalue , Object newValue ,IotSensorInfoBO sensor ){
		if( ObjectUtil.isEmpty(sensor.getStoreTime() ) ){
			sensor.setStoreTime(new Date());
		}
		Boolean flag = false ;
		if(sensor.getStore_strage()== null || sensor.getStore_strage() == 271 ){
			// 变化储存
			if( oldvalue instanceof  Float ){
				if( Float.parseFloat(oldvalue.toString())+0 != Float.parseFloat(newValue.toString()) ){
					flag = true ;
				}
			}else if( oldvalue instanceof  String ){
				if( !oldvalue.equals(newValue) ){
					flag = true ;
				}
			}
		}else if( sensor.getStore_strage() == 272 ){
			// 实时储存
			flag = true ;
		}else if( sensor.getStore_strage() == 273 ){
			// 30s
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 30) >= 0){
				flag = true ;
			}
		}else if( sensor.getStore_strage() == 274 ){
			// 1min
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 60) >= 0){
				flag = true ;
			}
		}else if( sensor.getStore_strage() == 275 ){
			// 5min
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 5*60) >= 0){
				flag = true ;
			}
		}else if( sensor.getStore_strage() == 276 ){
			// 10min
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 10*60) >= 0){
				flag = true ;
			}
		}else if( sensor.getStore_strage() == 277 ){
			// 30min
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 30*60) >= 0){
				flag = true ;
			}
		}else if( sensor.getStore_strage() == 278 ){
			// 1h
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 1*60*60) >= 0){
				flag = true ;
			}
		}else if( sensor.getStore_strage() == 279 ){
			// 1d
			if( DateUtils.getMinusFromCurrent(sensor.getStoreTime(), 1*24*60) >= 0){
				flag = true ;
			}
		}
		if(flag){
			sensor.setStoreTime(new Date());
		}
		return flag ;
	}

}
